package com.ruoyi.web.controller.algorithm;

import com.atkxp.dto.req.AlgorithmUpdateDTO;
import com.atkxp.dto.req.TempScratchPaperDTO;
import com.atkxp.dto.req.UploadScratchPaperDTO;
import com.atkxp.dto.resp.AlgorithmDTO;
import com.atkxp.dto.resp.AlgorithmDescDTO;
import com.atkxp.dto.resp.ScratchPaperDescDTO;
import com.atkxp.service.IAlgorithmService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import com.atkxp.dto.resp.Category;

import java.util.*;

/**
 * @author longhunpomie - 蒯兴鹏
 * @declaration
 * @email 3314028177@qq.com
 * @create 2025/3/29-17:04
 */
@RestController
@RequestMapping("/algorithm")
public class AlgorithmController {

    @Autowired
    private IAlgorithmService algorithmService;

    @GetMapping("/category.json")
    public Map getCategory() {
        Map res = new LinkedHashMap();

        List<Category> category = algorithmService.getAllCategory();

        if (category != null && !category.isEmpty()) {
            category.stream().forEach(x -> {
                List<AlgorithmDTO> algorithm = algorithmService.getAllAlgorithmByCategory(x.getCategory());
                Map algorithmMap = new LinkedHashMap();

                if (algorithm == null && algorithm.isEmpty()) {
                    algorithmMap.put("list", Collections.emptyList());
                } else {
                    Map<String, String> list = new LinkedHashMap<>();
                    algorithm.stream().forEach(al -> {
                        list.put(al.getName(), al.getAlgorithmName());
                    });
                    algorithmMap.put("list", list);
                }
                algorithmMap.put("name", x.getCategoryName());

                res.put(x.getCategory(), algorithmMap);
            });
        }

        return res;
    }

    @GetMapping("/review/category.json")
    public Map getReviewCategory() {
        Map res = new LinkedHashMap();

        List<Category> category = algorithmService.getAllReviewCategory();

        if (category != null && !category.isEmpty()) {
            category.stream().forEach(x -> {
                List<AlgorithmDTO> algorithm = algorithmService.getAllReviewAlgorithmByCategory(x.getCategory());
                Map algorithmMap = new LinkedHashMap();

                if (algorithm == null && algorithm.isEmpty()) {
                    algorithmMap.put("list", Collections.emptyList());
                } else {
                    Map<String, String> list = new LinkedHashMap<>();
                    algorithm.stream().forEach(al -> {
                        list.put(al.getName(), al.getAlgorithmName());
                    });
                    algorithmMap.put("list", list);
                }
                algorithmMap.put("name", x.getCategoryName());

                res.put(x.getCategory(), algorithmMap);
            });
        }

        return res;
    }

    @PostMapping("/review/online")
    public AjaxResult onlineAlgorithm(@RequestBody AlgorithmUpdateDTO req) {
        return algorithmService.onlineAlgorithm(req.getCategory(), req.getName());
    }

    @PostMapping("/review/refuse")
    public AjaxResult refuseAlgorithm(@RequestBody AlgorithmUpdateDTO req) {
        return algorithmService.refuseAlgorithm(req.getCategory(), req.getName());
    }

    @GetMapping("/scratch_paper/desc.json")
    public Map getScratchPaperDesc() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        Map map = new LinkedHashMap();
        String markdown = algorithmService.getScratchPaperDesc(user.getUserId());
        if(markdown == null || "".equals(markdown)) {
            map.put("markdown", "# 算法介绍部分，支持MarkDown语法");
        } else {
            map.put("markdown", markdown);
        }

        Map fileMap = new LinkedHashMap();

        List<ScratchPaperDescDTO> desc = algorithmService.getScratchPaperSimpleDesc(user.getUserId());
        if(!CollectionUtils.isEmpty(desc)) {
            desc.stream().forEach(x -> {
                fileMap.put(x.getFile(), x.getDesc());
            });
        } else {
            fileMap.put("basic", "这里输入你的可视化代码，详情参考可视化 API");
            fileMap.put("cpp_template", "这里输入你的算法模板");
        }
        map.put("files", fileMap);

        return map;
    }

    @GetMapping("/scratch_paper/{file}/data.js")
    public String getScratchPaperData(@PathVariable("file") String file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        return algorithmService.getScratchPaperData(user.getUserId(), file);
    }

    @GetMapping("/scratch_paper/{file}/code.js")
    public String getScratchPaperCode(@PathVariable("file") String file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        return algorithmService.getScratchPaperCode(user.getUserId(), file);
    }

    @GetMapping("/scratch_paper/{file}/template.txt")
    public String getScratchPaperTemplate(@PathVariable("file") String file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        return algorithmService.getScratchPaperTemplate(user.getUserId(), file);
    }

    @GetMapping("/{category}/{algorithm}/desc.json")
    public Map getAlgorithmDesc(@PathVariable("category") String category,
                                   @PathVariable("algorithm") String algorithm) {
        Map map = new LinkedHashMap();
        map.put("markdown", algorithmService.getDesc(category, algorithm));

        Map fileMap = new LinkedHashMap();

        List<AlgorithmDescDTO> desc = algorithmService.getSimpleDesc(category, algorithm);
        if(desc != null && !desc.isEmpty()) {
            desc.stream().forEach(x -> {
                fileMap.put(x.getFile(), x.getDesc());
            });
        }
        map.put("files", fileMap);
        return map;
    }

    @GetMapping("/{category}/{algorithm}/{file}/data.js")
    public String getAlgorithmData(@PathVariable("category") String category,
                                   @PathVariable("algorithm") String algorithm,
                                   @PathVariable("file") String file) {
        return algorithmService.getData(category, algorithm, file);
    }

    @GetMapping("/{category}/{algorithm}/{file}/code.js")
    public String getAlgorithmCode(@PathVariable("category") String category,
                                   @PathVariable("algorithm") String algorithm,
                                   @PathVariable("file") String file) {
        return algorithmService.getCode(category, algorithm, file);
    }

    @GetMapping("/{category}/{algorithm}/{file}/template.txt")
    public String getAlgorithmTemplate(@PathVariable("category") String category,
                                   @PathVariable("algorithm") String algorithm,
                                   @PathVariable("file") String file) {
        return algorithmService.getTemplate(category, algorithm, file);
    }

    @PostMapping("/scratch_paper/temp/save")
    public AjaxResult tempSaveScratchPaper(@RequestBody TempScratchPaperDTO data) {
        return algorithmService.tempSaveScratchPaper(data);
    }

    @PostMapping("/scratch_paper/upload")
    public AjaxResult uploadScratchPaper(@RequestBody UploadScratchPaperDTO data) {
        return algorithmService.uploadScratchPaper(data);
    }
}
